﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.IO;

namespace ParamSetCollection.General.Parameters.Normal
{
    public struct ShortBits
    {
        public ShortBits(ushort initialBitValue)
        {
            this.bits = initialBitValue;
        }

        public bool this[int index]
        {
            get
            {
                return (this.bits & (1 << index)) != 0;
            }

            set
            {
                if (value)//如果value为true，就将bit设为1（打开）；否则设为0（关闭）。
                {
                    this.bits |= (ushort)(1 << index);
                }
                else
                {
                    this.bits &= (ushort)~(1 << index);
                }
            }
        }

        public static implicit operator ShortBits(ushort from)
        {
            return new ShortBits(from);
        }

        public static implicit operator ushort(ShortBits from)
        {
            return from.bits;
        }

        private ushort bits;
    }

    public class ParamUnit//用于指令交互
    {
        public delegate void OnValueRenewEventHandler(ParamUnit pu);
        public event OnValueRenewEventHandler OnValueRenewEvent;


        public string Code = "";//变量名
        public Dictionary<string, string> Names = new Dictionary<string, string>();//自定义名称，与所选语言绑定
        public string MesName = "";//用于mes的名字

        public bool RemoteEnable = false;//允许上传
        public bool LogEnable = false;

        public string MesNameKey = "en";//选择mes上传时使用的名字语言

        public string m_value = "";//值
        public string Unit = "";//单位
        private string m_position = "0";//地址
        public string Format = "%d";//格式，%0.1f,%d, bit
        public string m_max = "1000";//最大值
        public string m_min = "0";//最小值

        public bool Valid = true;
        public string oldValue = "";//仅用于其他程序中间操作
        public bool MaxLock = false;//true时禁止修改Max的值，用于其他程序

        public bool DontRenewBufMark = false;//当为true时，不更新缓存里的值
        public string Value
        {
            get
            {
                if (Format.Contains("0."))
                {
                    double formatNumber = 1;
                    double valueBuff = 0;
                    if (double.TryParse(Format.Replace("%", "").Replace("f", ""), out formatNumber) && double.TryParse(m_value, out valueBuff))
                    {
                        formatNumber = formatNumber * 10;
                        valueBuff = valueBuff / Math.Pow(10, formatNumber);
                        return String.Format("{0:f" + formatNumber + "}", valueBuff);
                    }
                    else
                    {
                        return m_value;
                    }

                }
                else
                {
                    return m_value;
                }
            }
            set
            {
                OnValueRenewEvent?.Invoke(this.Clone());

                m_value = value;
                UpdatedMark = true;
            }
        }

        public string ViewValue
        {
            get
            {
                if (Format.Contains("0."))
                {
                    double formatNumber = 1;
                    double valueBuff = 0;
                    if (double.TryParse(Format.Replace("%", "").Replace("f", ""), out formatNumber) && double.TryParse(m_value, out valueBuff))
                    {
                        formatNumber = formatNumber * 10;
                        valueBuff = valueBuff / Math.Pow(10, formatNumber);
                        return String.Format("{0:f" + formatNumber + "}", valueBuff);
                    }
                    else
                    {
                        return m_value;
                    }

                }
                else
                {
                    return m_value;
                }
            }
            set
            {
                if (Format.Contains("0."))
                {
                    double formatNumber = 1;
                    double valueBuff = 0;
                    if (double.TryParse(Format.Replace("%", "").Replace("f", ""), out formatNumber) && double.TryParse(value, out valueBuff))
                    {
                        formatNumber = formatNumber * 10;
                        valueBuff = valueBuff * Math.Pow(10, formatNumber);
                        m_value = valueBuff.ToString("0");
                        UpdatedMark = true;
                    }
                    else
                    {
                        m_value = value;
                        UpdatedMark = true;
                    }

                }
                else
                {
                    m_value = value;
                    UpdatedMark = true;
                }

            }
        }

        public string Max
        {
            get
            {
               if (Format.Contains("0."))
                {
                    double formatNumber = 1;
                    double valueBuff = 0;
                    if (double.TryParse(Format.Replace("%", "").Replace("f", ""), out formatNumber) && double.TryParse(m_max, out valueBuff))
                    {
                        formatNumber = formatNumber * 10;
                        valueBuff = valueBuff / Math.Pow(10, formatNumber);
                        return String.Format("{0:f" + formatNumber + "}", valueBuff);
                    }
                    else
                    {
                        return m_max;
                    }

                }
                else
                {
                    return m_max;
                }
            }
            set
            {
                m_max = value;
                UpdatedMark = true;
            }
        }

        public string Min
        {
            get
            {
               if (Format.Contains("0."))
                {
                    double formatNumber = 1;
                    double valueBuff = 0;
                    if (double.TryParse(Format.Replace("%", "").Replace("f", ""), out formatNumber) && double.TryParse(m_min, out valueBuff))
                    {
                        formatNumber = formatNumber * 10;
                        valueBuff = valueBuff / Math.Pow(10, formatNumber);
                        return String.Format("{0:f" + formatNumber + "}", valueBuff);
                    }
                    else
                    {
                        return m_max;
                    }

                }
                else
                {
                    return m_min;
                }
            }
            set
            {
                m_min = value;
                UpdatedMark = true;
            }
        }

        public ParamUnit()
        {

        }

        public ParamUnit(string code, string mesName = "", bool remoteEnable = false, bool logEn = false, string value = "", string unit = "", string format = "1", string max = "", string min = "", string langKey = "en")
        {
            Code = code;
            
            MesName = mesName;

            RemoteEnable = remoteEnable;
            LogEnable = logEn;
            m_value = value;
            Unit = unit;
            Format = format;
            m_max = max;
            m_min = min;

            MesNameKey = langKey;
        }

        public static ParamUnit GetNewUnit(string code, string v)
        {
            ParamUnit pu = new ParamUnit();
            pu.Code = code;
            pu.Value = v;

            return pu;
        }

        public void ReadCfg(string path, string langKey)
        {
            if (File.Exists(path) == false)
                return;

            XmlDocument doc = new XmlDocument();
            try
            {
                doc.Load(path);
                XmlNode mainNode = doc.SelectSingleNode("ParamsList/" + Code);
                if (mainNode != null)
                {

                    for (int i = 0; i < mainNode.ChildNodes.Count; i++)
                    {
                        XmlNode pNod = mainNode.ChildNodes[i];
                        switch (pNod.Name)
                        {

                            case "MesName":
                                MesName = pNod.InnerText;
                                break;

                            case "Unit":
                                Unit = pNod.InnerText;
                                break;
                
                            case "Format":
                                Format = pNod.InnerText;
                                break;
                            case "Value":
                                Value = pNod.InnerText;
                                break;
                            case "Max":
                                Max = pNod.InnerText;
                                break;
                            case "Min":
                                Min = pNod.InnerText;
                                break;
                            default:
                                if (pNod.Name.Contains("Name"))
                                {
                                    if (Names.ContainsKey(pNod.Name) == false)
                                    {
                                        Names.Add(pNod.Name, pNod.InnerText);
                                    }

                                }

                                break;
                        }


                    }

                }


            }
            catch (Exception ex)
            {


            }



        }

        public void RenewOldValue()
        {
            oldValue = ViewValue;
        }

        public string ExTransformToViewValue(string str)
        {
           if (Format.Contains("0."))
            {
                double formatNumber = 1;
                double valueBuff = 0;
                if (double.TryParse(Format.Replace("%", "").Replace("f", ""), out formatNumber) && double.TryParse(str, out valueBuff))
                {
                    formatNumber = formatNumber * 10;
                    valueBuff = valueBuff / Math.Pow(10, formatNumber);
                    return String.Format("{0:f" + formatNumber + "}", valueBuff);
                }
                else
                {
                    return String.Format("{0:f" + formatNumber + "}", 0);
                }

            }
            else
            {
                return str;
            }
        }

        public string ExTransformToStoreValue(string str)
        {
         if (Format.Contains("0."))
            {
                double formatNumber = 1;
                double valueBuff = 0;
                if (double.TryParse(Format.Replace("%", "").Replace("f", ""), out formatNumber) && double.TryParse(str, out valueBuff))
                {
                    formatNumber = formatNumber * 10;
                    valueBuff = valueBuff * Math.Pow(10, formatNumber);
                    return valueBuff.ToString("0");
                }
                else
                {
                    return String.Format("{0:f" + formatNumber + "}", 0);
                }

            }
            else
            {
                return str;
            }
        }

        //返回存储值，传入显示值
        public bool CheckValue(string v, out string validValue)
        {

            validValue = m_value;//存储值，非显示值


            bool rs = false;

            Single vBuf = 0;
            Single max = 0;
            Single min = 0;
            rs = Single.TryParse(Max, out max);
            if (rs == false)
            {
                return false;
            }

            rs = Single.TryParse(Min, out min);
            if (rs == false)
            {
                return false;
            }

            rs = Single.TryParse(v, out vBuf);
            if (rs == false)
            {
                return false;
            }

            if (vBuf < min || vBuf > max)
            {
                return false;
            }


            if (Format.Contains("0."))
            {
                double formatNumber = 1;
                decimal valueBuff = 0;
                if (double.TryParse(Format.Replace("%", "").Replace("f", ""), out formatNumber))
                {
                    formatNumber = formatNumber * 10;
                    valueBuff = (decimal)vBuf * (decimal)Math.Pow(10, formatNumber);
                    validValue = ((int)valueBuff).ToString();
                }


            }
            else
            {
                validValue = ((int)vBuf).ToString();
            }

            return true;
        }


        public string GetRangeTip()
        {
            string str = Min + " ~ " + Max;
            return str;
        }

        public bool UpdatedMark = false;//更新标志

        public ParamUnit Clone()
        {
            ParamUnit pu = new ParamUnit();

            pu.Code = Code;

            foreach (var key in Names.Keys)
            {
                pu.Names.Add(key, Names[key]);
            }
    
            pu.MesName = MesName;
           

            pu.RemoteEnable = RemoteEnable;
            pu.LogEnable = LogEnable;
            pu.MesNameKey = MesNameKey;

            pu.m_value = m_value;
            pu.Unit = Unit;
            pu.Format = Format;
            pu.m_max = m_max;
            pu.m_min = m_min;

            pu.DontRenewBufMark = DontRenewBufMark;

            return pu;
        }
    }
}
